package com.mindmax.user.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ArrayUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import com.mindmax.user.domain.*;
import com.mindmax.user.service.*;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.enums.DataSourceType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 租户管理Controller
 *
 * @author cablo
 * @date 2024-04-02
 */
@DataSource(value = DataSourceType.YT_ADMIN)
@RestController
@RequestMapping("/b/tenant")
public class TenantController extends BaseController
{
    @Autowired
    private ITenantService tenantService;

    @Autowired
    private ITenantUserService tenantUserService;

    @Autowired
    private IYtRoleService ytRoleService;

    @Autowired
    private IInviteCodeService inviteCodeService;





    @PreAuthorize("@ss.hasPermi('b:tenant:list')")
    @GetMapping("/search")
    public AjaxResult search(String query)
    {

       return success(tenantService.searchByTenantName(query)) ;
    }



    /**
     * 查询租户管理列表
     */
    @PreAuthorize("@ss.hasPermi('b:tenant:list')")
    @GetMapping("/list")
    public TableDataInfo list(Tenant tenant)
    {
        startPage();
        List<Tenant> list = tenantService.selectTenantList(tenant);
        List<Long>        ids = list.stream().map(Tenant::getId).distinct().collect(Collectors.toList());
        logger.info("ids:{}", ids);
        List<InviteCodeResult> m =  inviteCodeService.selectInviteCodeByTenantIds(ids);
        Map<Long, InviteCodeResult> inviteCodeMap = Maps.newHashMap();
        if (CollectionUtils.isNotEmpty(m)) {
            logger.info("m is {}", JSON.toJSONString(m));
            inviteCodeMap
                    = m.stream().collect(Collectors.toMap(InviteCodeResult::getTenantId,
                    Function.identity(), (v1, v2) -> v1));
        }

        List<Map<String, Object>> maps = tenantUserService.selectCountByTenant(ids);
        logger.info("maps:{}", maps);
// 使用Stream API转换结果集
        Map<Long, Integer> tenantIdToCountMap = maps.stream()
                .collect(Collectors.toMap(
                        result ->  Long.valueOf(String.valueOf(result.get("tenantId"))), // 作为键的函数
                        result ->  Integer.valueOf(String.valueOf(result.get("count")))
                ));

        for (Tenant t : list) {
            t.setUserAmount(tenantIdToCountMap.getOrDefault(t.getId(), 0));
            t.setInviteCode(inviteCodeMap.getOrDefault(t.getId(), new InviteCodeResult()).getInviteCode());
            t.setInviteCodeExpireTime(inviteCodeMap.getOrDefault(t.getId(), new InviteCodeResult()).getExpireTime());
        }
        return getDataTable(list);
    }

    /**
     * 导出租户管理列表
     */
    @PreAuthorize("@ss.hasPermi('b:tenant:export')")
    @Log(title = "租户管理", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, Tenant tenant)
    {
        List<Tenant>      user = tenantService.selectTenantList(tenant);
        ExcelUtil<Tenant> util = new ExcelUtil<Tenant>(Tenant.class);
        util.exportExcel(response, user, "租户管理数据");
    }

    /**
     * 获取租户管理详细信息
     */
    @PreAuthorize("@ss.hasPermi('b:tenant:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(tenantService.selectTenantById(id));
    }



    @Autowired
    private ITenantResourceService tenantResourceService;


    @PreAuthorize("@ss.hasPermi('b:tenant:edit')")
    @PutMapping(value = "setUserIsAdmin")
    public AjaxResult setUserIsAdmin(@RequestBody TenantUser tenantUser) {
        logger.info("setUserIsAdmin: {}", JSON.toJSONString(tenantUser));
        var userId   = tenantUser.getUserId();
        var tenantId = tenantUser.getTenantId();

        tenantUserService.setUserIsAdmin(userId, tenantId);

        return success();

    }

    /**
     * 新增租户管理
     */
    @PreAuthorize("@ss.hasPermi('b:tenant:add')")
    @Log(title = "租户管理", businessType = BusinessType.INSERT)
    @PostMapping
    @Transactional(rollbackFor = Throwable.class)
    public AjaxResult add(@RequestBody Tenant tenant) {

        Long userId = getUserId();
        tenant.setCreateUser(userId);
        tenant.setUpdateUser(userId);
        logger.info("tenant:{}", JSON.toJSONString(tenant));
        int        insertCount = tenantService.insertTenant(tenant);
        List<Long> menuIds     = tenant.getMenuIds();
        if (CollectionUtil.isNotEmpty(menuIds)) {
            Long tenantId = tenant.getId();
            tenantResourceService.deleteTenantResourceByTenantId(tenantId);
            for (Long menuId : menuIds) {
                TenantResource tenantResource = new TenantResource();
                tenantResource.setTenantId(tenantId);
                tenantResource.setResourceId(menuId);
                tenantResource.setCreateBy(tenant.getCreateBy());
                tenantResource.setUpdateBy(tenant.getUpdateBy());
                tenantResource.setCreateTime(tenant.getCreateTime());
                tenantResource.setUpdateTime(tenant.getUpdateTime());
                tenantResource.setRemark(tenant.getRemark());
                tenantResourceService.insertTenantResource(tenantResource);
            }
        }

        ytRoleService.deleteYtRoleByTenantId(tenant.getId());
        YtRole ytRole = new YtRole();
        ytRole.setTenantId(tenant.getId());
        ytRole.setRoleName("系统管理员");
        ytRole.setDeleted(0);
        ytRole.setManager(1);
        ytRole.setCreateUser(userId);
        ytRole.setUpdateUser(userId);
        ytRole.setCreateTime(tenant.getCreateTime());
        ytRole.setUpdateTime(tenant.getUpdateTime());
        ytRoleService.insertYtRole(ytRole);
        logger.info("ytRole inserted successfully.{}", JSON.toJSONString(ytRole));
        return toAjax(insertCount);
    }

    /**
     * 修改租户管理
     */
    @PreAuthorize("@ss.hasPermi('b:tenant:edit')")
    @Log(title = "租户管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Tenant tenant)
    {
        tenantResourceService.deleteTenantResourceByTenantId(tenant.getId());
        List<Long> menuIds = tenant.getMenuIds();
        if (CollectionUtil.isNotEmpty(menuIds)) {
            for (Long menuId : menuIds) {
                TenantResource tenantResource = new TenantResource();
                tenantResource.setTenantId(tenant.getId());
                tenantResource.setResourceId(menuId);
                tenantResource.setCreateBy(tenant.getCreateBy());
                tenantResource.setUpdateBy(tenant.getUpdateBy());
                tenantResource.setCreateTime(tenant.getCreateTime());
                tenantResource.setUpdateTime(tenant.getUpdateTime());
                tenantResourceService.insertTenantResource(tenantResource);
            }
        }
        return toAjax(tenantService.updateTenant(tenant));
    }

    /**
     * 删除租户管理
     */
    @PreAuthorize("@ss.hasPermi('b:tenant:remove')")
    @Log(title = "租户管理", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        if (ArrayUtil.isNotEmpty(ids)) {
            for (Long id : ids) {
                tenantResourceService.deleteTenantResourceByTenantId(id);
            }
            return toAjax(tenantService.deleteTenantByIds(ids));

        }

        return success();
    }
}
